<template>
  <div>
    <el-dialog v-model="props.visible"
      :title="`${props.type === 'add' ? '新增' : props.type === 'edit' ? '编辑' : '查看'}计分标准`" width="800px" align-center
      @close="emits('cancel')">
      <el-form ref="formRef" :model="form" :rules="rules">
        <el-form-item label="类别" prop="typeId" label-width="80px">
          <el-select v-if="props.type !== 'view'" v-model="form.typeId" placeholder="请选择">
            <el-option v-for="item in typeOptions" :key="item.value" :label="item.title" :value="item.value" />
          </el-select>
          <div v-else>{{ form.typeName }}</div>
        </el-form-item>
        <el-form-item label="量化指标" prop="name" label-width="80px">
          <el-input v-if="props.type !== 'view'" v-model="form.name" type="textarea" placeholder="请输入" :maxlength="100"
            show-word-limit />
          <div v-else>{{ form.name }}</div>
        </el-form-item>
        <el-form-item label="计算方式" prop="type" label-width="80px">
          <el-radio-group v-model="form.type" :disabled="props.type === 'view'" @change="handleType">
            <el-radio :value="1">单个计算</el-radio>
            <el-radio :value="2">阶梯计算</el-radio>
            <el-radio :value="3">金额计算</el-radio>
            <el-radio :value="4">等同计算</el-radio>
            <el-radio :value="5">其他</el-radio>
          </el-radio-group>
        </el-form-item>
        <div class="flex">
          <span class="min-w-[80px]" />
          <!-- 单个计算 -->
          <div v-if="form.type === 1" class="flex space-x-[12px]">
            <el-form-item label="单位" prop="unitId" :rules="{ validator: validator, trigger: 'change' }">
              <el-select v-model="form.unitId" placeholder="请选择" :disabled="props.type === 'view'"
                style="width: 150px;">
                <el-option v-for="item in unitOptions" :key="item.value" :label="item.title" :value="item.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="分值" prop="mark" :rules="{ validator: validator, trigger: 'blur' }">
              <el-input-number v-model="form.mark" :disabled="props.type === 'view'" :min="0" :max="9999.99"
                :controls="false" :precision="2" style="width: 90px;" />
            </el-form-item>
          </div>
          <!-- 阶梯计算 -->
          <div v-if="form.type === 2">
            <div class="flex space-x-[12px]">
              <el-form-item label="单位" prop="unit" :rules="{ validator: validator, trigger: 'blur' }"
                label-width="70px">
                <el-input-number v-model="form.unit" :disabled="props.type === 'view'" :min="0" :max="9999.99"
                  :controls="false" :precision="2" style="width: 170px;" />
              </el-form-item>
              <el-select v-model="form.unitEnum" :disabled="props.type === 'view'" placeholder="请选择"
                style="width: 90px;">
                <el-option :value="2" label="万元" />
                <el-option :value="1" label="元" />
              </el-select>
            </div>
            <div v-for="(item, index) in form.ladder" :key="`${index}`" class="flex items-center space-x-[12px]">
              <el-form-item :label="ladderList[index]" :prop="`ladder[${index}].statMoney`"
                :rules="{ validator: validator, trigger: 'blur' }" label-width="70px">
                <el-input-number v-model="item.statMoney" :disabled="props.type === 'view'" :min="0" :max="9999.99"
                  :controls="false" :precision="2" style="width: 170px;">
                  <template #suffix>
                    <span>{{ unitEnumMap[form.unitEnum as keyof typeof unitEnumMap] }}</span>
                  </template>
                </el-input-number>
              </el-form-item>
              <el-form-item label="＜到账经费≤" :prop="`ladder[${index}].endMoney`"
                :rules="{ validator: validator, trigger: 'blur' }" label-width="90px">
                <el-input-number v-model="item.endMoney" :disabled="props.type === 'view'" :min="0" :max="9999.99"
                  :controls="false" :precision="2" style="width: 170px;"
                  @change="(cur, old) => endMoneyDebounce(cur, old, index)">
                  <template #suffix>
                    <span>{{ unitEnumMap[form.unitEnum as keyof typeof unitEnumMap] }}</span>
                  </template>
                </el-input-number>
              </el-form-item>
              <el-form-item label="分值" :prop="`ladder[${index}].mark`"
                :rules="{ validator: validator, trigger: 'blur' }" label-width="40px">
                <el-input-number v-model="item.mark" :disabled="props.type === 'view'" :min="0" :max="9999.99"
                  :controls="false" :precision="2" style="width: 70px;" />
              </el-form-item>
              <el-icon v-if="props.type !== 'view' && index > 0" size="16px"
                class="h-[34px] leading-[34px] mb-[18px] cursor-pointer" @click="handleDelete(index)">
                <Close />
              </el-icon>
            </div>
            <div v-if="props.type !== 'view'" class="flex justify-center mt-[2px]">
              <el-button round :icon="Plus" @click="handleAdd">新增</el-button>
            </div>
            <div class="mt-[12px] leading-[22px]">
              <span class="text-[#F53F3F]">*</span><span
                class="text-[#86909C]">计算规则：如到账金额为550万元，则第一阶梯分值为100*25/10，第二阶梯分值为400*12.5/10，第三阶梯为50*6.25/10。总分为100*25/10+400*12.5/10+50*6.25/10。</span>
            </div>
          </div>
          <!-- 金额计算 -->
          <div v-if="form.type === 3">
            <div class="flex space-x-[12px]">
              <div class="flex space-x-[8px]">
                <el-form-item label="单位" prop="unit" :rules="{ validator: validator, trigger: 'blur' }"
                  label-width="40px">
                  <el-input-number v-model="form.unit" :disabled="props.type === 'view'" :min="0" :max="9999.99"
                    :controls="false" :precision="2" style="width: 90px;" />
                </el-form-item>
                <el-select v-model="form.unitEnum" placeholder="请选择" :disabled="props.type === 'view'"
                  style="width: 90px;">
                  <el-option :value="2" label="万元" />
                  <el-option :value="1" label="元" />
                </el-select>
              </div>
              <el-form-item label="分值" prop="mark" :rules="{ validator: validator, trigger: 'blur' }"
                label-width="40px">
                <el-input-number v-model="form.mark" :disabled="props.type === 'view'" :min="0" :max="9999.99"
                  :controls="false" :precision="2" style="width: 150px;" />
              </el-form-item>
            </div>
            <div class="mt-[2px]">
              <span class="text-[#F53F3F]">*</span><span class="text-[#86909C]">计算规则：如金额为50万元，则科研分为50*30。</span>
            </div>
          </div>
          <!-- 等同计算 -->
          <div v-if="form.type === 4">
            <div class="flex space-x-[12px]">
              <el-form-item label="等同于" prop="equivalentTypeId" :rules="{ validator: validator, trigger: 'change' }"
                label-width="55px">
                <el-select v-model="form.equivalentTypeId" placeholder="计分类别" clearable
                  :disabled="props.type === 'view'" style="width: 150px;" @change="handleEquivalenTypeChange">
                  <el-option v-for="item in assessmentCalculationTypeList" :key="item.id" :label="item.name"
                    :value="item.id" />
                </el-select>
              </el-form-item>
              <el-form-item label="" prop="equivalentId" :rules="{ validator: validator, trigger: 'change' }">
                <el-select v-model="form.equivalentId" placeholder="量化指标" clearable
                  :disabled="!form.equivalentTypeId || props.type === 'view'" style="width: 150px;">
                  <el-option v-for="item in assessmentCalculationNameList" :key="item.id" :label="item.name"
                    :value="item.id" />
                </el-select>
              </el-form-item>
            </div>
            <div class="mt-[2px]">
              <span class="text-[#F53F3F]">*</span><span class="text-[#86909C]">计算规则：与等同的量化指标计算方式一致。</span>
            </div>
          </div>
          <!-- 其他 -->
          <div v-if="form.type === 5">
            <span class="text-[#F53F3F]">*</span><span class="text-[#86909C]">计算规则：不做自动计算，科研分由教师输入。</span>
          </div>
        </div>
      </el-form>
      <template #footer>
        <div v-if="props.type !== 'view'" class="dialog-footer">
          <el-button @click="emits('cancel', false)">取消</el-button>
          <el-button type="primary" :loading="addLoading || updateLoading" @click="handleSubmit">确认</el-button>
        </div>
        <div v-else class="dialog-footer">
          <el-button @click="emits('cancel', false)">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { ladderList, unitEnumMap } from '@/utils/constText'
import {
  assessmentMethodCreateAssessmentCalculation,
  assessmentMethodUpdateAssessmentCalculation,
  assessmentMethodDetailAssessmentCalculation,
  assessmentMethodListAssessmentCalculation
} from '@/api/assessment';
import { AssessmentMethodCalculationListRespVO, BaseSuccessRespDTO } from '@/api/assessment/types';
import { dictEnum } from '@/utils/constEnum';
import { debounce } from 'lodash'

const { proxy } = getCurrentInstance()
const dict = proxy.useDict(dictEnum.manageCategory, dictEnum.unit)

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  id: {
    type: String,
    default: ''
  },
  assessmentMethodId: {
    type: String,
    default: ''
  },
  type: {
    type: String,
    default: ''
  }
})

interface AssessmentCalculate {
  id?: string
  name?: string
  children?: AssessmentCalculate[]
}

const emits = defineEmits(['cancel'])

const formRef = ref()
const form = ref({
  typeId: '',
  typeName: '',
  name: '',
  type: 1,
  mark: undefined,
  unit: undefined,
  unitId: '',
  calculationMethodId: '',
  ladder: [],
  unitEnum: 2,
  equivalentTypeId: '',
  equivalentTypeName: '',
  equivalentId: '',
  equivalentName: '',
})

const rules = ref({
  typeId: [{ required: true, message: "类别不能为空", trigger: "change" }],
  name: [{ required: true, message: "量化指标不能为空", trigger: "blur" }],
  type: [{ required: true, message: "计算方式不能为空", trigger: "blur" }],
})

const typeOptions = computed(() => dict[dictEnum.manageCategory] || [])
const unitOptions = computed(() => dict[dictEnum.unit] || [])

const assessmentCalculationTypeList = ref<AssessmentCalculate[]>([])
const assessmentCalculationNameList = ref<AssessmentCalculate[]>([])

const { run: assessmentMethodCalculationList } = useRequest(() => assessmentMethodListAssessmentCalculation({
  calculationId: props.id,
  assessmentMethodId: props.assessmentMethodId
}), {
  manual: true,
  onSuccess: (res: AssessmentMethodCalculationListRespVO[]) => {
    const data: { [property: string]: AssessmentCalculate } = {}
    res?.forEach(item => {
      if (data[item.typeId as string]) {
        (data?.[item.typeId as string]?.children as AssessmentCalculate[]).push({
          id: item.calculationMethodId as string,
          name: item.name as string
        })
      } else {
        data[item.typeId as string] = {
          id: item.typeId,
          name: item.typeName,
          children: [{
            id: item.calculationMethodId,
            name: item.name
          }]
        }
      }
    })
    assessmentCalculationTypeList.value = Object.values(data) || []
    if (form.value.equivalentTypeId) {
      assessmentCalculationNameList.value = assessmentCalculationTypeList.value.find(item => item.id === form.value.equivalentTypeId)?.children || []
    }
  }
})

const { run: getDetail } = useRequest(() => assessmentMethodDetailAssessmentCalculation({
  id: props.id
}), {
  manual: true,
  onSuccess: (res: AssessmentMethodCalculationListRespVO) => {
    form.value = {
      typeId: res?.typeId as string,
      typeName: res?.typeName as string,
      name: res?.name as string,
      type: res?.type as number,
      unitId: res?.unitId as string,
      mark: res?.mark as number,
      unit: res?.unit as number,
      rewardMethodId: res?.rewardMethodId as string,
      calculationMethodId: res?.calculationMethodId as string,
      ladder: res?.ladder || [],
      unitEnum: res?.unitEnum,
      equivalentTypeId: res?.equivalentTypeId,
      equivalentId: res?.calculationMethodId,
      equivalentTypeName: res?.equivalentTypeName,
      equivalentName: res?.equivalentName,
    }
    assessmentMethodCalculationList()
  }
})

const { run: create, loading: addLoading } = useRequest(assessmentMethodCreateAssessmentCalculation, {
  manual: true,
  onSuccess: (res: BaseSuccessRespDTO) => {
    if (res?.isSuccess) {
      ElMessage({
        message: '新增成功!',
        type: 'success',
        plain: true,
      })
      emits('cancel', true)
    }
  }
})

const { run: update, loading: updateLoading } = useRequest(assessmentMethodUpdateAssessmentCalculation, {
  manual: true,
  onSuccess: (res: BaseSuccessRespDTO) => {
    if (res?.isSuccess) {
      ElMessage({
        message: '更新成功!',
        type: 'success',
        plain: true,
      })
      emits('cancel', true)
    }
  }
})

const endMoneyChange = (current: number | undefined, old: number | undefined, index: number) => {
  if (current !== old) {
    // 最后一个阶段不自动填入
    if (form.value.ladder?.length - 1 !== index) {
      form.value.ladder[index + 1].statMoney = current
    }
  }
}

const endMoneyDebounce = debounce(endMoneyChange, 500)

const handleAdd = () => {
  form.value.ladder.push({
    statMoney: undefined,
    endMoney: undefined,
    mark: undefined
  })
}

const handleDelete = (index) => {
  form.value.ladder.splice(index, 1)
}

const handleEquivalenTypeChange = (val: string) => {
  form.value.equivalentId = ''
  if (!val) {
    assessmentCalculationNameList.value = []
  } else {
    assessmentCalculationNameList.value = assessmentCalculationTypeList.value.find(item => item.id === val)?.children || []
  }
}

const handleType = (val: string | number | boolean) => {
  if (val === 1) {
    form.value = {
      typeId: form.value.typeId,
      name: form.value.name,
      type: val,
      unitId: '',
      mark: undefined
    }
  } else if (val === 2) {
    form.value = {
      typeId: form.value.typeId,
      name: form.value.name,
      type: val,
      unitEnum: 2,
      unit: undefined,
      ladder: [{
        statMoney: undefined,
        endMoney: undefined,
        mark: undefined
      }]
    }
  } else if (val === 3) {
    form.value = {
      typeId: form.value.typeId,
      name: form.value.name,
      type: val,
      unit: undefined,
      unitEnum: 2,
      mark: undefined
    }
  }
  else if (val === 4) {
    form.value = {
      typeId: form.value.typeId,
      name: form.value.name,
      type: val,
      calculationMethodId: '',
      equivalentTypeId: '',
      equivalentId: '',
    }
  } else {
    form.value = {
      typeId: form.value.typeId,
      name: form.value.name,
      type: val,
    }
  }
}

const handleSubmit = () => {
  formRef.value.validate(valid => {
    if (valid) {
      let params = {
        typeId: form.value.typeId,
        name: form.value.name,
        type: form.value.type
      }
      if (form.value.type === 1) {
        params = {
          ...params,
          unitId: form.value.unitId,
          mark: form.value.mark,
        }
      } else if (form.value.type === 2) {
        params = {
          ...params,
          unitEnum: form.value.unitEnum,
          unit: form.value.unit,
          ladder: form.value.ladder,
          mark: form.value.ladder?.map(item => item.mark)?.join('/')
        }
      } else if (form.value.type === 3) {
        params = {
          ...params,
          mark: form.value.mark,
          unit: form.value.unit,
          unitEnum: form.value.unitEnum
        }
      } else if (form.value.type === 4) {
        params = {
          ...params,
          calculationMethodId: form.value.equivalentId,
        }
      }
      if (props.id) {
        update({ ...params, id: props.id })
      } else {
        create({ ...params, assessmentMethodId: props.assessmentMethodId })
      }
    }
  })
}

const validator = (rule: any, value: any, callback: any) => {
  if (!value && value !== 0) {
    return callback(new Error('不能为空'))
  }
  callback()
}

watch(() => props.visible, () => {
  if (props.visible) {
    if (props.id) {
      getDetail()
    } else {
      assessmentMethodCalculationList()
    }
  }
}, { immediate: true })
</script>

<style scoped lang="scss">
:deep(.el-textarea__inner) {
  min-height: 120px !important;
}

:deep(.el-input-number .el-input__inner) {
  text-align: left;
}
</style>